`timescale 1ns / 1ps
`include "vending_machine_mix1.v"

//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/12/16 09:34:45
// Design Name:
// Module Name: vending_machine_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////



// module vending_machine_mix1_tb;

//     // �����źŶ���
//     reg clk;
//     reg rst;
//     reg [2:0] coin;
//     reg [1:0] sel;
//     reg goods_num_query;
//     wire dispense;
//     wire [3:0] change;
//     wire low_balance;
//     wire [3:0] balance;
//     wire [3:0] num_goods_disp;

//     // ʵ�����Զ��ۻ���ģ��
//     vending_machine uut (
//         .clk(clk),
//         .rst(rst),
//         .coin(coin),
//         .sel(sel),
//         .goods_num_query(goods_num_query),
//         .dispense(dispense),
//         .change(change),
//         .low_balance(low_balance),
//         .balance(balance),
//         .num_goods_disp(num_goods_disp)
//     );

//     // ʱ������
//     initial clk = 0;
//     always #5 clk = ~clk;

//     // �������񣺼����
//     task check_output;
//         input string test_name;
//         input dispense_exp;
//         input [3:0] change_exp;
//         input low_balance_exp;
//         input [3:0] balance_exp;
//         begin
//             #10; // �ȴ�ģ����Ӧ
//             if (dispense == dispense_exp && change == change_exp &&
//                 low_balance == low_balance_exp && balance == balance_exp) begin
//                 $display("%s: PASSED", test_name);
//             end else begin
//                 $display("%s: FAILED", test_name);
//                 $display("    Expected: dispense=%b, change=%d, low_balance=%b, balance=%d",
//                          dispense_exp, change_exp, low_balance_exp, balance_exp);
//                 $display("    Got:      dispense=%b, change=%d, low_balance=%b, balance=%d",
//                          dispense, change, low_balance, balance);
//             end
//         end
//     endtask

//     // ��������
//     initial begin
//         // ��ʼ���ź�
//         rst = 1; coin = 0; sel = 0; goods_num_query = 0;
//         #20; rst = 0;

//         // ����1��Ͷ�Ҳ�������ƷA
//         coin = 3'b001; // Ͷ1Ԫ
//         #10; coin = 3'b010; // Ͷ2Ԫ
//         #10; coin = 3'b001; // ��Ͷ1Ԫ
//         sel = 2'b01; // ѡ����ƷA
//         check_output("Test 1: Buy A", 1, 0, 0, 0);

//         // ����2�����㹺����ƷB
//         coin = 3'b010; // Ͷ2Ԫ
//         #10; sel = 2'b10; // ѡ����ƷB
//         check_output("Test 2: Low Balance B", 0, 0, 1, 2);

//         // ����3��Ͷ�ҹ�����ƷB
//         coin = 3'b010; // ��Ͷ2Ԫ
//         #10; sel = 2'b10; // ѡ����ƷB
//         check_output("Test 3: Buy B", 1, 0, 0, 0);

//         // ����4������ѯ
//         goods_num_query = 1;
//         sel = 2'b01; // ��ѯ��ƷA���
//         #10;
//         if (num_goods_disp == 3) begin
//             $display("Test 4: Query A Stock PASSED");
//         end else begin
//             $display("Test 4: Query A Stock FAILED");
//             $display("    Expected: 3, Got: %d", num_goods_disp);
//         end
//         goods_num_query = 0;

//         // ����5����Ʒ��治��
//         coin = 3'b100; // Ͷ5Ԫ
//         #10; sel = 2'b11; // ѡ����ƷC
//         check_output("Test 5: Out of Stock C", 0, 0, 1, 5);

//         $stop; // ֹͣ����
//     end

//     //��������
//     initial begin
//         $dumpfile("vending_machine_mix1_tb.vcd"); // VCD�ļ����ڲ�����ʾ
//         $dumpvars(0, vending_machine_mix1_tb);    // ������б���
//     end

// endmodule



//*************************************************************************************************
//last2
// module vending_machine_mix1_tb;

//     // �˿��źŶ���
//     reg clk;                // ʱ��
//     reg rst;                // ��λ
//     reg [2:0] coin;         // Ͷ������ (1, 2, 5Ԫ)
//     reg [1:0] sel;          // ��Ʒѡ�� (01: A, 10: B, 11: C)
//     wire dispense;          // ��Ʒ����ź�
//     wire [4:0] change;      // ������
//     wire low_balance;       // �����ź�
//     wire [4:0] balance;     // ��ǰ���

//     // ʵ����������ģ��
//     vending_machine_mix1 uut (
//                              .clk(clk),
//                              .rst(rst),
//                              .coin(coin),
//                              .sel(sel),
//                              .dispense(dispense),
//                              .change(change),
//                              .low_balance(low_balance),
//                              .balance(balance)
//                          );

//     // ����ʱ��
//     initial begin
//         clk = 0;
//         forever
//             #5 clk = ~clk; // 10ns���ڵ�ʱ��
//     end

//     // ��������
//     initial begin
//         // ��ʼ���ź�
//         rst = 1;
//         coin = 3'b000;
//         sel = 2'b00;
//         #20; // �ȴ���λ

//         rst = 0; // ȡ����λ
//         #10;

//         // ��������1��Ͷ��1Ԫ��ѡ����ƷA�����㣩
//         coin = 3'b001; // Ͷ1Ԫ
//         #10;
//         coin = 3'b000; // ֹͣͶ��
//         sel = 2'b01;   // ѡ����ƷA
//         #20;
//         sel = 2'b00;   // ���ѡ��
//        // #200000
//         if (low_balance) begin
//             $display("Y ��������1ͨ��: ���㣬�޷�������ƷA      dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end
//         else begin
//             $display("N ��������1ʧ��: �����㣬��Ԥ��Ӧ����   dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end

//         // ��������2��Ͷ��5Ԫ��ѡ����ƷA���۸�4Ԫ��
//         coin = 3'b100; // Ͷ5Ԫ
//         #10;
//         coin = 3'b000;
//         sel = 2'b01;   // ѡ����ƷA
//         #20;
//         sel = 2'b00;   // ���ѡ��
//         if (dispense == 1&& change == 1) begin
//             $display("Y ��������2ͨ��: ������ƷA������������ȷ  dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end
//         else begin
//             $display("N ��������2ʧ��: ������ƷA���������㲻��ȷ  dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end

//         // ��������3��Ͷ��2Ԫ + 2Ԫ + 2Ԫ��ѡ����ƷB���۸�6Ԫ��
//         coin = 3'b010; // Ͷ2Ԫ
//         #10;
//         coin = 3'b010; // ��Ͷ2Ԫ
//         #10;
//         coin = 3'b010; // ��Ͷ2Ԫ
//         #10;
//         coin = 3'b000;
//         sel = 2'b10;   // ѡ����ƷB
//         #20;
//         sel = 2'b00;
//         if (dispense == 1 && change == 0) begin
//             $display("Y ��������3ͨ��: ������ƷB������������ȷ dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end
//         else begin
//             $display("N ��������3ʧ��: ������ƷB���������㲻��ȷ  dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end

//         // ��������4��Ͷ��5Ԫ + 5Ԫ��ѡ����ƷC���۸�8Ԫ��
//         coin = 3'b100; // Ͷ5Ԫ
//         #10;
//         coin = 3'b100; // ��Ͷ5Ԫ
//         #10;
//         coin = 3'b000;
//         sel = 2'b11;   // ѡ����ƷC
//         #20;
//         sel = 2'b00;
//         if (dispense == 1 && change == 2) begin
//             $display("Y ��������4ͨ��: ������ƷC������������ȷ");
//         end
//         else begin
//             $display("N ��������4ʧ��: ������ƷC���������㲻��ȷ  dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end

//         //��������5��Ͷ�ҳ��޲���
//         repeat (7) begin
//             coin=3'b100;//ÿ��Ͷ��5Ԫ
//         #10;
//         end
//             coin=3'b000;//ֹͣͶ��
//         #20;
//         //�ж�����Ƿ�����Ϊ���ֵ31
//         if (balance == 31) begin
//             $display("Y ��������5ͨ����Ͷ�ҳ�����ȷ����             dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end
//         else begin
//             $display("N ��������5ʧ�ܣ�Ͷ�ҳ���δ���� dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
//         end


//         // ��������6����λ����
//         rst = 1;
//         #10;
//         rst = 0;
//         if (balance == 0 && !dispense && change == 0) begin
//             $display("Y ��������6ͨ��: ��λ��������Ч�����ź���ȷ");
//         end
//         else begin
//             $display("N ��������6ʧ��: ��λ��������Ч�����źŲ���ȷ");
//         end

//         //��������7:��ʱ����
//         #200000;
//         if (low_balance == 0 && dispense == 0 && change == 0) begin
//             $display("Y ��������7ͨ��: ��ʱ������ȷ");
//         end
//         else begin
//             $display("N ��������7ʧ��: ��ʱ��������");
//         end

//         #50;
//         $finish; // ��������
//     end

//     // ��ʾ����
//     initial begin
//         $dumpfile("vending_machine_mix1_tb.vcd"); // VCD�ļ����ڲ�����ʾ
//         $dumpvars(0, vending_machine_mix1_tb);    // ������б���
//     end

// endmodule

module vending_machine_mix1_tb;
    reg clk;
    reg rst;
    reg [2:0] coin;
    reg [1:0] sel;
    wire dispense;
    wire [4:0] balance;
    wire [4:0] change;
    wire low_balance;


    // 实例化贩卖机模块
    vending_machine_mix1 uut (
                             .clk(clk),
                             .rst(rst),
                             .coin(coin),
                             .sel(sel),
                             .dispense(dispense),
                             .balance(balance),
                             .change(change),
                             .low_balance(low_balance)
                         );


    // Clock generation
    initial begin
        clk = 0;
        forever
            #5 clk = ~clk; // 10ns clock period
    end

    // 测试序列
    initial begin
        // 初始化信号
        rst = 1;
        coin = 3'b000;
        sel = 2'b00;
        #10; // 等待复位

        rst = 0; // 取消复位

        // Test 1: Insert 1Ԫ and select A (balance insufficient)
        coin = 3'b001; // 1Ԫ
        #10;
        coin = 0;
        sel = 2'b01; // Select A
        #10;
        sel = 0;
        #20;
        if (dispense == 0 && change == 1 && low_balance == 1 && balance == 0) begin
            $display("Y 测试用例1通过:    dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end
        else begin
            $display("N 测试用例1失败:    dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end

        // Test 2: Insert 5Ԫ and select A (successful purchase)
        coin = 3'b100; // 5Ԫ
        #10;
        coin = 0;
        sel = 2'b01; // Select A
        #10;
        sel = 0;
        #20;
        if (dispense == 1 && change == 1 && low_balance == 0 && balance == 0) begin
            $display("Y 测试用例2通过:  dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end
        else begin
            $display("N 测试用例2失败:  dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end

         // Test 3: Insert 2Ԫ 3   and select B (successful purchase)
        coin = 3'b010; // 2Ԫ
        #10;
        coin = 0;
        #10;
        coin = 3'b010; // 2Ԫ
        #10;
        coin = 0;
        #10;
        coin = 3'b010; // 2Ԫ
        #10;
        coin = 0;
        sel = 2'b10; // Select B
        #10;
        sel = 0;
        #20;
        if (dispense == 1 && change == 0 && low_balance == 0 && balance == 0) begin
            $display("Y 测试用例3通过: dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end
        else begin
            $display("N 测试用例3失败: dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end

        // Test 4: Insert 5Ԫ and select C (successful purchase with change)
        coin = 3'b100; // 5Ԫ
        #10;
        coin = 0;
        #10
        coin = 3'b100;
        #10
        coin = 0;
        sel = 2'b11; // Select C
        #10;
        sel = 0;
        #20;
        if (dispense == 1 && change == 2 && low_balance == 0 && balance == 0) begin
            $display("Y 测试用例5通过: dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end
        else begin
            $display("N 测试用例5失败: dispense=%b, change = %d, low_balance=%b, balance=%d", dispense, change, low_balance, balance);
        end

                //         5  Ͷ ҳ  ޲   
        repeat (7) begin
            coin=3'b100;//ÿ  Ͷ  5Ԫ
        #10;
        end
            coin=3'b000;//ֹͣͶ  
        #20;

        $finish; // 结束仿真
    end

    // 显示波形
    initial begin
        $dumpfile("vending_machine_mix1_tb.vcd"); // VCD文件用于波形显示
        $dumpvars(0, vending_machine_mix1_tb);    // 监控所有变量
    end

endmodule


// module vending_machine_mix1_tb;

//     // �˿��źŶ���
//     reg clk;                // ʱ��
//     reg rst;                // ��λ
//     reg [2:0] coin;         // Ͷ������ (1, 2, 5Ԫ)
//     reg [1:0] sel;          // ��Ʒѡ�� (01: A, 10: B, 11: C)
//     wire dispense;          // ��Ʒ����ź�
//     wire [3:0] change;      // ������
//     wire low_balance;       // �����ź�
//     wire [3:0] balance;     // ��ǰ���

//     // ʵ����������ģ��
//     vending_machine_mix1 uut (
//         .clk(clk),
//         .rst(rst),
//         .coin(coin),
//         .sel(sel),
//         .dispense(dispense),
//         .change(change),
//         .low_balance(low_balance),
//         .balance(balance)
//     );

//     // ����ʱ��
//     initial begin
//         clk = 0;
//         forever #5 clk = ~clk; // 10ns���ڵ�ʱ��
//     end

//     // ��������
//     initial begin
//         // ��ʼ���ź�
//         rst = 1;
//         coin = 3'b000;
//         sel = 2'b00;
//         #20; // �ȴ���λ

//         rst = 0; // ȡ����λ
//         #10;

//         // ��������1��Ͷ��1Ԫ��ѡ����ƷA�����㣩
//         coin = 3'b001; // Ͷ1Ԫ
//         #10;
//         coin = 3'b000; // ֹͣͶ��
//         sel = 2'b01;   // ѡ����ƷA
//         #20;
//         sel = 2'b00;   // ���ѡ��

//         // ��������2��Ͷ��5Ԫ��ѡ����ƷA���۸�4Ԫ��
//         coin = 3'b100; // Ͷ5Ԫ
//         #10;
//         coin = 3'b000;
//         sel = 2'b01;   // ѡ����ƷA
//         #20;
//         sel = 2'b00;   // ���ѡ��

//         // ��������3��Ͷ��2Ԫ + 2Ԫ + 2Ԫ��ѡ����ƷB���۸�6Ԫ��
//         coin = 3'b010; // Ͷ2Ԫ
//         #10;
//         coin = 3'b010; // ��Ͷ2Ԫ
//         #10;
//         coin = 3'b010; // ��Ͷ2Ԫ
//         #10;
//         coin = 3'b000;
//         sel = 2'b10;   // ѡ����ƷB
//         #20;
//         sel = 2'b00;

//         // ��������4��Ͷ��5Ԫ + 5Ԫ��ѡ����ƷC���۸�8Ԫ��
//         coin = 3'b100; // Ͷ5Ԫ
//         #10;
//         coin = 3'b100; // ��Ͷ5Ԫ
//         #10;
//         coin = 3'b000;
//         sel = 2'b11;   // ѡ����ƷC
//         #20;
//         sel = 2'b00;

//         // ��������5����λ����
//         rst = 1;
//         #10;
//         rst = 0;

//         #50;
//         $finish; // ��������
//     end

//     // ��ʾ����
//     initial begin
//         $dumpfile("vending_machine_mix1_tb.vcd"); // VCD�ļ����ڲ�����ʾ
//         $dumpvars(0, vending_machine_mix1_tb);    // ������б���
//     end

// endmodule

//*************************************************************************************************

